import i18n from '@/i18n'
import type { DishwasherController } from './definition'
import type { Worker } from '@/controller/base/types/worker'
import type { Remote } from '@/controller/base/types/remote'
import { useWorker, useRemote, wrapSafeActions } from '@/controller/base/index'
import { RemoteTypes } from '@/controller/base/remote'
import { createBaseState, BaseGetters, BaseActions, createBaseApplianceControl } from '../BaseAppliance'
import { defineStore } from 'pinia'
import { getValidProgramOptions, useProgramEffects } from '../common/Program/program'
import {
  createPowerOutageState,
  PowerOutageGetters,
  PowerOutageActions,
  usePowerOutageEffects,
} from '../common/PowerOutage/powerOutage'
import {
  DISHWASHER_STATUS_PHASE,
  PRESENT,
  DISHWASHER_OPTION_FLEXSPRAY,
  BSH_COMMOM_PROGRAM_FAVORITE_001,
  BSH_COMMOM_PROGRAM_FAVORITE_002,
  BSH_COMMON_SETTING_FAVORITE_001_PROGRAM,
  BSH_COMMON_SETTING_FAVORITE_002_PROGRAM,
  BSH_COMMON_OPRION_BASEPROGRAM,
  START_IN_RELATIVE,
  FINISH_IN_RELATIVE,
  DISHWASHER_STORAGEFUNCTIONACTIVE,
  CONFIRMED,
  DISHWASHER_OPTION_FLEXSPRAY_BACKLEFT,
  DISHWASHER_OPTION_FLEXSPRAY_BACKRIGHT,
  DISHWASHER_OPTION_FLEXSPRAY_FRONTLEFT,
  DISHWASHER_OPTION_FLEXSPRAY_FRONTRIGHT,
  DISHERWASHER_VARIO_SPEED_PLUS,
  DISHWASHER_VENTEDSTORAGEACTIVE,
  DISHWASHER_SETTING_DRYINGASSISTANT,
  SMART_DRYING_KEY,
  DISHWASHER_OPTION_VENTEDSTORAGE,
  DISHWASHER_OPTION_STORAGEFUNCTION,
  DISHWASHER_OPTION_FLEXSPRAY_PREFIX,
} from '@/constants/Command'
import type { ApplianceProgram } from '@/types/appliance'
import type {
  FavoriteProgramsType,
  FavoriteProgramsValueType,
} from '@/pages/appliance/Dishwasher/editFavoriteProgram/editFavoriteProgram.vue'
import { useControlState } from '@/controller/BaseAppliance/useControl'
import _ from 'lodash'
import { LearningActions, LearningGetters, createLearningState, useLearningEffects } from './Learning/learning'
import { LearningProgramKey } from './Learning/constants'
import { safeTrack } from '@/dataReport/dataReportUtil'
import type { TrackData } from '@/dataReport/components/TrackTypes'
import type { ApplianceDetailOption, ProgramSelectOption } from '@/api/appliance'
import { TrackType, trackEvent } from '@/dataReport/tracks'
import type { Notice } from '@/types/notice'


/**
 * 初始化数据
 */
export const createDishwasherState: () => DishwasherController.State = () => ({
  ...createBaseState(),
  ...createPowerOutageState(),
  ...createLearningState(),
  // 状态
  usingHistoryPrograms: true,
  flexSpraySupported: false,
  adjustParameterTitle: i18n.global.t('Dishwasher.customProgram.AdjustParams.Label.Text'),
  // 自定义程序
  customProgramOption: null,
  programPhase: null,
  isStorage: false,
  isActiveEcoDry: false,
  isStorageOption: false,
  flexSprayList: [],
})
export const DishwasherGetters: DishwasherController.Getters = {
  ...BaseGetters,
  ...PowerOutageGetters,
  ...LearningGetters,
  isSui({ _datasource: { detail } }) {
    return detail?.vibLabel?.some((item) => item.label == 'Dishwasher_SUI') || false
  },

  // 已排序的全部程序列表
  sortedAllPrograms() {
    if (!Array.isArray(this.allPrograms) || this.allPrograms.length === 0) return []

    // 如果是自定义进行排序
    const sortCustom = !this.isSui && this.hasFavoriteFunction
    // 程序排序
    const sortedPrograms = getSortedPrograms(this.allPrograms, sortCustom)

    return sortedPrograms
  },
  favoriteProgramsSui(store) {
    let settings = store._datasource.settings || []
    return settings.reduce<FavoriteProgramsType[]>((favoritePrograms, item) => {
      if (item.key === BSH_COMMON_SETTING_FAVORITE_001_PROGRAM) {
        favoritePrograms[0] = {
          key: item.key,
          value: item.value as FavoriteProgramsValueType[],
        }
      } else if (item.key === BSH_COMMON_SETTING_FAVORITE_002_PROGRAM) {
        favoritePrograms[1] = {
          key: item.key,
          value: item.value as FavoriteProgramsValueType[],
        }
      }
      return favoritePrograms
    }, [])
  },
  // 使用适配SUI的程序列表
  customizedAllPrograms() {
    if (!Array.isArray(this.allPrograms) || this.allPrograms.length === 0) return []

    // 如果是自定义进行排序
    const sortCustom = !this.isSui && this.hasFavoriteFunction
    // 程序排序
    const sortedPrograms = getSortedPrograms(this.allPrograms, sortCustom)

    if (this.isSui) {
      return getSUIProgramList(sortedPrograms, this.favoriteProgramsSui)
    } else if (this.hasFavoriteFunction && !this.isSui) {
      return getCustomProgramList(sortedPrograms, this.customBaseName)
    }

    return sortedPrograms
  },
  // 预约使用的程序列表
  customizedOrderAllPrograms() {
    if (this.isSui) {
      return this.sortedAllPrograms.filter((program: ApplianceProgram.Scope) => {
        return ![BSH_COMMOM_PROGRAM_FAVORITE_001, BSH_COMMOM_PROGRAM_FAVORITE_002].includes(program.key)
      })
    }
    return this.sortedAllPrograms
  },
  // 是否强制隐藏暂停程序按钮
  hidePauseForced() {
    return true
  },
  // 支持精控强洗的洗碗机 防抖500ms刷新程序剩余时间 防止抖动
  remainingDebouncedTime() {
    return this.flexSpraySupported ? 500 : 0
  },
  // 是否强制禁用收藏程序
  favoriteForceDisabled() {
    return true
  },
  // 是否检查启动时间在谷电时间相近范围内
  shouldCheckValleyTimeApproching() {
    const relativeOption = this.availableParameter?.options?.find((option) =>
      [START_IN_RELATIVE, FINISH_IN_RELATIVE].includes(option.key)
    )
    // 未找到 RELATIVE Option 不检查
    if (!relativeOption) return false

    // FINISH_IN_RELATIVE 且无剩余时间 算不出开始时间 无法定位 跳过检查谷电时间
    if (relativeOption.key === FINISH_IN_RELATIVE && this.programRemaining === 0) return false

    // 其他情况检查谷电时间
    return true
  },
  // 当前选择自定义程序
  customProgramSelected() {
    return this.currentProgramKey === BSH_COMMOM_PROGRAM_FAVORITE_001
  },

  // 需要忽略的调节参数Key
  customIgnoredOptionKeys() {
    const keys = [
      DISHWASHER_OPTION_FLEXSPRAY,
      DISHWASHER_OPTION_FLEXSPRAY_FRONTLEFT,
      DISHWASHER_OPTION_FLEXSPRAY_FRONTRIGHT,
      DISHWASHER_OPTION_FLEXSPRAY_BACKLEFT,
      DISHWASHER_OPTION_FLEXSPRAY_BACKRIGHT,
    ]
    if (this.learningProgramSelected) {
      keys.push(DISHERWASHER_VARIO_SPEED_PLUS)
    }
    return keys
  },
  // 需要忽略的显示参数Key
  customIgnoredDisplayOptionKeys() {
    return this.customIgnoredOptionKeys.filter((key) => ![DISHWASHER_OPTION_FLEXSPRAY].includes(key))
  },

  // 报错特殊处理
  // SMM洗碗机 确认跳转到远程控制等级
  showControlLevelTipsOnRemoteControlError() {
    return this.isSMM
  },
  // 是否有未设置的家电面板程序
  hasNotSettedFavorite() {
    if (!this.allPrograms || this.allPrograms.length === 0) return false
    return (
      !judgeHaveSettedFavorite(this.allPrograms, this.favoriteProgramsSui[0]?.value?.[0]?.key) ||
      !judgeHaveSettedFavorite(this.allPrograms, this.favoriteProgramsSui[1]?.value?.[0]?.key)
    )
  },
  customBaseName({ _datasource: { settings } }) {
    let isExistCustom = this.hasFavoriteFunction && !this.isSui
    if (!isExistCustom) return ''
    let baseName = this.customProgramOption?.displayvalue || ''
    if (!baseName && settings.length > 0) {
      settings.forEach((item) => {
        if (
          item.key === BSH_COMMON_SETTING_FAVORITE_001_PROGRAM &&
          Array.isArray(item.value) &&
          item.value.length > 0
        ) {
          baseName = (item.value as FavoriteProgramsValueType[])[0]?.name || ''
        }
      })
    }
    return baseName
  },

  /**
   * CLS
   */
  flexSprayAdjustTitle() {
    switch (this._datasource.brand.toUpperCase()) {
      case 'BOSCH':
        return i18n.global.t('Dishwasher.Flexspray.AdjustParams.BOSCH.Title.Text')
      case 'SIEMENS':
      default:
        return i18n.global.t('Dishwasher.Flexspray.AdjustParams.SIEMENS.Title.Text')
    }
  },
  flexSprayModalTitle() {
    switch (this._datasource.brand.toUpperCase()) {
      case 'BOSCH':
        return i18n.global.t('Dishwasher.Flexspray.BOSCH.Title.Text')
      case 'SIEMENS':
      default:
        return i18n.global.t('Dishwasher.Flexspray.SIEMENS.Title.Text')
    }
  },
  flexSprayContentTitle() {
    switch (this._datasource.brand.toUpperCase()) {
      case 'BOSCH':
        return i18n.global.t('Dishwasher.Flexspray.Content.BOSCH.Title.Text')
      case 'SIEMENS':
      default:
        return i18n.global.t('Dishwasher.Flexspray.Content.SIEMENS.Title.Text')
    }
  },
}
export const DishwasherActions: DishwasherController.Actions = wrapSafeActions<
  DishwasherController.Store,
  DishwasherController.Actions
>({
  ...BaseActions,
  ...PowerOutageActions,
  ...LearningActions,
  customDisplayOptionFormatter(option: ProgramSelectOption) {
    if (option.key === DISHWASHER_OPTION_FLEXSPRAY) {
      // demo家电不存在 selectedOptions，改用 detailOptions 取值
      const detailOptions: ApplianceDetailOption[] = this.detail?.option || []
      if (!detailOptions.length) return null

      // 过滤出四个方位的值
      const description = [
        DISHWASHER_OPTION_FLEXSPRAY_BACKLEFT,
        DISHWASHER_OPTION_FLEXSPRAY_BACKRIGHT,
        DISHWASHER_OPTION_FLEXSPRAY_FRONTLEFT,
        DISHWASHER_OPTION_FLEXSPRAY_FRONTRIGHT,
      ]
        .map((key) => {
          // CLS关键字 如 'FrontLeft' | 'FrontRight'
          const keyword = key.replace(`${DISHWASHER_OPTION_FLEXSPRAY_PREFIX}.`, '')
          const flexSprayOption = detailOptions.find((detailOption) => detailOption.key === key)
          if (!flexSprayOption?.displayvalue) return ''

          const labelText = i18n.global.t(`Dishwasher.Flexspray.DisplayOption.${keyword}.Text`)
          return `${labelText} (${flexSprayOption.displayvalue})`
        })
        .filter((name) => name !== '')
        .join('、')

      return {
        key: option.key,
        label: this.flexSprayContentTitle,
        value: description,
      }
    }

    return null
  },
  async startProgramNow(program: ApplianceProgram.Scope, options: ProgramSelectOption[], buttonId) {
    await BaseActions.startProgramNow.call(this, program, options, buttonId, true)
    const validOptions = getValidProgramOptions(options)
    safeTrack(() => {
      // 立即启动埋点处理
      const trackData: TrackData = {
        program_key: '',
        program_name: '',
      }
      let DataArry: ProgramSelectOption[] = []
      if (this.flexSprayList.length > 0) {
        this.flexSprayList?.map((items) => {
          DataArry.push({ key: items.key, value: items.value })
        })
      }
      validOptions.map((items) => {
        DataArry.push(items)
      })

      trackData.program_key = program.key || ''
      trackData.program_name = program.name || ''
      if (DataArry.length > 0) {
        DataArry.map((items, index) => {
          trackData[`option_obj_${index + 1}`] = items
        })
      }
      trackEvent('start_program', trackData, TrackType.ApplianceDetail, buttonId)
    })
  },
})

export const DishwasherObserve: Remote.Observe<DishwasherController.Store> = {
  [DISHWASHER_STATUS_PHASE]: (_, remote) => remote.loadSupportCommands(),
}

/**
 * 组合API
 */
const useStore = defineStore<
  'Dishwasher',
  DishwasherController.State,
  DishwasherController.Getters,
  DishwasherController.Actions
>('Dishwasher', {
  state: createDishwasherState,
  getters: DishwasherGetters,
  actions: DishwasherActions,
})

// 组件使用
export function useDishwasherControl(): DishwasherController.Control {
  const store = useStore() as DishwasherController.Store
  const worker = useWorker(store) as Worker.ApplianceWorker<DishwasherController.Store>
  const remote = useRemote(store) as Remote.ApplianceRemote<DishwasherController.Store>
  return { store, worker, remote }
}

// 页面使用
export function createDishwasherControl(
  control: DishwasherController.Control = useDishwasherControl()
): DishwasherController.Control {
  const { store, worker, remote } = control

  createBaseApplianceControl(control, {
    remoteType: RemoteTypes.Inhouse,
  })
  const { showControlView } = useControlState(control)

  worker.onLoad(async () => {
    const tasks: Promise<void>[] = [
      // 加载状态
      remote.loadAllStatus(),
      remote.loadAllSetting(),
    ]
    // 显示详情页程序列表时 调用程序列表接口
    if (showControlView.value) {
      tasks.push(store.loadAllPrograms())
    }
    await Promise.all(tasks)
    await store.loadPowerSetting()
  })

  remote.addObserve(DishwasherObserve)
  remote.addBatchObserves([SuiBatchObserve, CustomBatchObserve])
  useProgramEffects(control)
  // 电源控制 断电命令
  usePowerOutageEffects(control)
  // Learning Effects
  useLearningEffects(control)

  useDishwasherBinding(control)

  return control
}

/**
 * 监听sui洗碗机自定义程序的修改
 */
const SuiBatchObserve: Remote.BatchObserve<DishwasherController.Store> = {
  matcher(msg, remote) {
    return remote.store.isSui && /^BSH\.Common\.Setting\.Favorite\.(\d+)\.Program$/.test(msg.key)
  },
  handler() {
    this.loadAllSetting()
  },
}

/**
 * 监听自定义程序
 */
const CustomBatchObserve: Remote.BatchObserve<DishwasherController.Store> = {
  matcher(msg, remote) {
    return (
      !remote.store.isSui &&
      remote.store.hasFavoriteFunction &&
      /^BSH\.Common\.Setting\.Favorite\.(\d+)\.Functionality$/.test(msg.key)
    )
  },
  handler() {
    this.store.loadAllPrograms()
  },
}

/**
 * 程序列表排序
 */
function getSortedPrograms(programs: ApplianceProgram.Scope[], sortCustom: boolean) {
  const sortedPrograms = [...programs]
  // 自定义排序
  if (sortCustom) {
    const customProgramIndex = sortedPrograms.findIndex((program) => program.key === BSH_COMMOM_PROGRAM_FAVORITE_001)
    if (customProgramIndex !== -1) {
      //自定义程序排第二
      const customProgram = sortedPrograms[customProgramIndex]
      sortedPrograms.splice(customProgramIndex, 1)
      sortedPrograms.unshift(customProgram)
    }
  }

  // 查找AI智洗程序
  const learningProgramIndex = sortedPrograms.findIndex((program) => program.key === LearningProgramKey)
  if (learningProgramIndex !== -1) {
    // AI智洗程序排第一
    const learningProgram = sortedPrograms[learningProgramIndex]
    sortedPrograms.splice(learningProgramIndex, 1)
    sortedPrograms.unshift(learningProgram)
  }

  return sortedPrograms
}

/**
 * 适配custom自定义程序名称
 */
function getCustomProgramList(programs: ApplianceProgram.Scope[], customBaseName: string) {
  let sortedPrograms = programs.map((program) => {
    if (program.key === BSH_COMMOM_PROGRAM_FAVORITE_001) {
      program.name = '自定义-' + customBaseName
    }
    return {
      ...program,
    }
  })
  return sortedPrograms
}

/**
 * 适配SUI的程序列表
 */
function getSUIProgramList(
  programs: ApplianceProgram.Scope[],
  favorites: FavoriteProgramsType[]
): ApplianceProgram.LocalProgramType[] {
  let haveFavoriteOne = judgeHaveSettedFavorite(programs, favorites[0]?.value?.[0]?.key)
  let favoriteKeyOne = haveFavoriteOne ? favorites[0]?.value?.[0]?.key : ''
  let favoriteNameOne = haveFavoriteOne
    ? favorites[0]?.value?.[0]?.name
    : i18n.global.t('Dishwasher.Sui.ProgramList.NoneProgram.Text')
  let haveFavoriteTwo = judgeHaveSettedFavorite(programs, favorites[1]?.value?.[0]?.key)
  let favoriteKeyTwo = haveFavoriteTwo ? favorites[1]?.value?.[0]?.key : ''
  let favoriteNameTwo = haveFavoriteTwo
    ? favorites[1]?.value?.[0]?.name
    : i18n.global.t('Dishwasher.Sui.ProgramList.NoneProgram.Text')
  let favoriteBaseKeys: string[] = [favoriteKeyOne, favoriteKeyTwo]

  // 若programs中没有面板程序则添加该key
  let favoriteys = [BSH_COMMOM_PROGRAM_FAVORITE_001, BSH_COMMOM_PROGRAM_FAVORITE_002]
  favoriteys.forEach((item) => {
    if (!judgeHaveSettedFavorite(programs, item)) {
      programs.push({
        constraints: { execution: 'selectandstart' },
        key: item,
        mediumDescription: '可通过晶御智能APP自由定义程序',
        name: '',
      })
    }
  })

  let sortedPrograms = programs
    .filter((program) => {
      return !favoriteBaseKeys.includes(program.key)
    })
    .map((program) => {
      if (program.key === BSH_COMMOM_PROGRAM_FAVORITE_001) {
        program.name = favoriteNameOne
      } else if (program.key === BSH_COMMOM_PROGRAM_FAVORITE_002) {
        program.name = favoriteNameTwo
      }
      return {
        ...program,
        isLocalLeft: [BSH_COMMOM_PROGRAM_FAVORITE_001].includes(program.key),
        isLocalRight: [BSH_COMMOM_PROGRAM_FAVORITE_002].includes(program.key),
        isNullProgram:
          (program.key === BSH_COMMOM_PROGRAM_FAVORITE_001 && !haveFavoriteOne) ||
          (program.key === BSH_COMMOM_PROGRAM_FAVORITE_002 && !haveFavoriteTwo),
      }
    })

  // 面板程序-右
  const favorite_002_Index = sortedPrograms.findIndex((program) => program.isLocalRight)
  if (favorite_002_Index !== -1) {
    const favorite002Program = sortedPrograms[favorite_002_Index]
    sortedPrograms.splice(favorite_002_Index, 1)
    sortedPrograms.unshift(favorite002Program)
  }
  // 面板程序-左
  const favorite_001_Index = sortedPrograms.findIndex((program) => program.isLocalLeft)
  if (favorite_001_Index !== -1) {
    const favorite001Program = sortedPrograms[favorite_001_Index]
    sortedPrograms.splice(favorite_001_Index, 1)
    sortedPrograms.unshift(favorite001Program)
  }

  return sortedPrograms
}

function useDishwasherBinding(control: DishwasherController.Control) {
  const { store, worker } = control

  worker.useHasKeyBinding('flexSpraySupported', {
    key: DISHWASHER_OPTION_FLEXSPRAY,
    from: 'detailOption',
  })
  worker.useGetValueBinding('customProgramOption', {
    key: BSH_COMMON_OPRION_BASEPROGRAM,
    from: 'detailOption',
    patcher: (patchState, reference) => {
      patchState.customProgramOption = reference.item
    },
  })
  // 获取运行阶段数据
  worker.useGetValueBinding('programPhase', {
    key: DISHWASHER_STATUS_PHASE,
    from: 'status',
  })

  // 抑菌储存
  const StorageKeys = [DISHWASHER_STORAGEFUNCTIONACTIVE, DISHWASHER_VENTEDSTORAGEACTIVE]
  StorageKeys.forEach((key) => {
    worker.useGetValueBinding('isStorage', {
      key,
      from: 'event',
      patcher: (patchState, reference) => {
        patchState.isStorage = [PRESENT, CONFIRMED].includes(reference.value as string)
      },
    })
  })
  // 智能烘干
  worker.useGetValueBinding('isActiveEcoDry', {
    key: DISHWASHER_SETTING_DRYINGASSISTANT,
    from: 'event',
  })
  worker.useGetValueBinding('isActiveEcoDry', {
    key: SMART_DRYING_KEY,
    from: 'detailOption',
  })

  //存储功能
  const StorageOptionKeys = [DISHWASHER_OPTION_VENTEDSTORAGE, DISHWASHER_OPTION_STORAGEFUNCTION]
  StorageOptionKeys.forEach((key) => {
    worker.useGetValueBinding('isStorageOption', {
      key,
      from: 'detailOption',
    })
  })
}

function judgeHaveSettedFavorite(programs: ApplianceProgram.Scope[], favoriteKey: string) {
  if (!programs || programs.length === 0) return false
  return programs.some((item) => item.key === favoriteKey)
}
